package com.bruce.starts.demo.commonerror.transaction.demo;

import jodd.util.concurrent.ThreadFactoryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class WovenBatchThreadPoolExcutor {
    private static final Logger logger = LoggerFactory.getLogger(WovenBatchThreadPoolExcutor.class);
    private PlatformTransactionManager transactionManager;
    private int taskSize;

    public WovenBatchThreadPoolExcutor(PlatformTransactionManager transactionManager, int taskSize) {
        this.transactionManager = transactionManager;
        this.taskSize = taskSize;
    }

    /**
     * 构建批量事务线程池
     * @return
     */
    private ThreadPoolExecutor createThreadPoolExecutor(int corePoolSize, int maxPoolSize, long keepAliveTime, String poolName,
                                                        TimeUnit unit, BlockingQueue<Runnable> workQueue, BatchTransactionInfo info) {
        ThreadFactory nameFactory = new ThreadFactoryBuilder().setNameFormat(poolName + "%d").get();
        return new ThreadPoolExecutor(corePoolSize, maxPoolSize, keepAliveTime, unit, workQueue, nameFactory) {
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                //批量事务
                if (info.isBatchTransaction()) {
                    //任务是否完成
                    try {
                        while (info.getCompleteThreads().get()!= info.getGroupSize()) {
                            logger.info(Thread.currentThread().getName() + " 等待主线程：getGroupSize:" + info.getGroupSize() + "\tgetCompleteThreads：" + info.getCompleteThreads().get());
                            logger.info("开启事务个数：" + info.getLongTransactionStatusMap().size());
                            Thread.sleep(100);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    TransactionStatus transactionStatus = info.getLongTransactionStatusMap().get(Thread.currentThread().getId());
                    if (info.getSuccessThreads().get() == info.getCompleteThreads().get()) {
                        transactionManager.commit(transactionStatus);
                    } else {
                        transactionManager.rollback(transactionStatus);
                    }
                }
            }
        };
    }
}
